【VFX】PlayRateでエフェクトの速度を変更する

December 02, 2022


以下のエフェクトの速度を動的に変更したい。

ParticleSystemではタイムスケールを設定する項目がありましたがVFXでは playRate がそれに該当します

単純にコードを書くと

public class PlayRateTest : MonoBehaviour
{
		/* Define & Class */


		/* Public Field */


		/* Private Field */

		[SerializeField] private VisualEffect _visualEffect;
		[SerializeField] private float _rate = 1f;

		/* Property */


		/* Public Method */


		/* Private Method */


		/* Monobehaviour */
		
		private void Awake()
		{
			_visualEffect = GetComponent<VisualEffect>();
		}

		private void Start()
		{
		}

		private void Update()
		{
			_visualEffect.playRate = _rate;
		}

		private void OnDestroy()
		{
		}
}

これで _rate に応じて速度が変更されます。 値は 1 が通常速度で 0 が完全停止します

↓ 値を 10 にした時

PlayRateはEditorでVFXを再生していると右下にでるWindow内の Rate の値です

C0D3C77BAB1C94C52EC36A075BF9D894

ここで注意点として スクリプト上で 1f と定義した時、Windowの値は 100 だということ

スクリプト上で10 をしている時、上記Windowでは 1000 が表示されています。 WindowのRate値に惑わされないように注意が必要です。

そしてWindow上では4000までしか指定できませんが、スクリプト上では4000以上の値も設定可能となります

Timescale との組み合わせ

例えば TIme.Timescaleの値を 0.1 にして世界をスローモーションにしてみます

DE6A5BF52E784E47D483BB0BF7B62082

これで世界は 1/10 スローになりますが、特定のVFXはスローにさせたくないケースを考えます

TimeScale が 0.1 に指定されているのであれば playrate の値を 10 にしてみると良さそうです。 しかし値をそのまま設定しただけでは動きがカクついています

Timescale が 0.1 となったことで fixedDeltaTime の値も 1/10 になり影響が出ています。 VFXの更新周期をその分上げる必要があります

コード上からでは VFXManager.fixedTimeStepで設定が可能です 適当に rate から同期秒数を指定出来るように変更しました

public class PlayRateTest : MonoBehaviour
	{
		/* Define & Class */


		/* Public Field */


		/* Private Field */

		[SerializeField] private VisualEffect _visualEffect;
		[SerializeField] private float _rate = 1f;

		private float _fixedTimeStep;

		/* Property */


		/* Public Method */


		/* Private Method */


		/* Monobehaviour */
		
		private void Awake()
		{
			_visualEffect = GetComponent<VisualEffect>();

			_fixedTimeStep = VFXManager.fixedTimeStep;
		}

		private void Start()
		{
		}

		private void Update()
		{
			_visualEffect.playRate = _rate;

			VFXManager.fixedTimeStep = _fixedTimeStep / _rate;
		}

		private void OnDestroy()
		{
		}
	}

この状態で実行したのが以下

動きもなめらかになりました。 TimeScaleで世界は遅いままですがVFXのEffectには影響が出ていません。

fixedTimeStep は ProjectSettings の VFX に項目があります

0957AC9138DD79EFD508D75580A1D1C1

参考

https://docs.unity3d.com/ja/2021.3/ScriptReference/VFX.VisualEffect-playRate.html

https://docs.unity3d.com/ja/2019.4/ScriptReference/VFX.VFXManager-fixedTimeStep.html